package com.sdry.web.controller.workplace;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Controller;

import com.sdry.model.lz.DeviceModel;
import com.sdry.model.workplace.Centrifugal;
import com.sdry.model.workplace.CentrifugalExample;
import com.sdry.model.workplace.CentrifugalExample.Criteria;
import com.sdry.model.workplace.WorkCentrifugalDetails;
import com.sdry.service.workplace.CentrifugalServise;
import com.sdry.service.workplace.OthersService;
import com.sdry.service.workplace.WorkCentrifugalDetailsService;

@Controller
public class RunStartTwo implements ApplicationListener<ContextRefreshedEvent> {
	@Resource
	WorkCentrifugalDetailsService workCentrifugalDetailsService;
	@Resource
	private OthersService othersService;
	@Resource
	private CentrifugalServise centrifugalServise;

	private static final Log LOGGER = LogFactory.getLog(RunStartTwo.class);

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		try {
			// 在web项目中（spring mvc），系统会存在两个容器，一个是root application context
			// ,另一个就是我们自己的 projectName-servlet context（作为root application
			// context的子容器）。
			// 这种情况下，就会造成onApplicationEvent方法被执行两次。为了避免这个问题，我们可以只在root
			// application context初始化完成后调用逻辑代码，其他的容器的初始化完成，则不做任何处理。
			if (event.getApplicationContext().getParent() == null) {
				// 需要实现的功能
//				System.out.println("随项目启动方式二----------------》");
				try {
					connect("COM7");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			LOGGER.error("StartGateServiceData", e);
		}
	}

	private static SerialPort serialPort;

	public void connect(String portName) throws Exception {
		CommPortIdentifier portIdentifier = CommPortIdentifier
				.getPortIdentifier(portName);
		if (portIdentifier.isCurrentlyOwned()) {
//			System.out.println("Error: Port is currently in use");
		} else {
			CommPort commPort = portIdentifier.open(this.getClass().getName(),
					2000);
			if (commPort instanceof SerialPort) {
				serialPort = (SerialPort) commPort;
				serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
						SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

				InputStream in = serialPort.getInputStream();
				(new Thread(new SerialReader(in))).start();
				byte[] buffer = new byte[1024];
//				System.out.println("=============" + in.read(buffer));
			} else {
//				System.out.println("Error: Only serial ports are handled by this example.");
			}
		}
	}

	/** 读串口数据 */
	public class SerialReader implements Runnable {
		InputStream in;

		public SerialReader(InputStream in) {
			this.in = in;
		}

		public void run() {
			byte[] buffer = new byte[1024];
			int len = -1;
			try {
				while ((len = this.in.read(buffer)) > -1) {
					String getValue = new String(buffer, 0, len);
					if (getValue != null && getValue.length() > 2) {
						// 获取值往另一个地方丢
						// serialPort.close();
						// ApplicationContextHelper.test(getValue);
//						System.out.println(getValue);
						Map<String, Object> map = stringZhuanMap(getValue);
						String message = addCentrifugalDetails(map);
						// 获取输出流，利用输出流发送数据
						OutputStream outputStream = serialPort
								.getOutputStream();
						outputStream.write((message).getBytes("GB2312"));
						outputStream.close();
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public Map<String, Object> stringZhuanMap(String s) {
		// s = "{\"a\":\"1\",\"b\":2,\"c\":\"2016-5\"}";
		Map<String, Object> m = new HashMap<String, Object>();
		String[] split = s.split(",");
		for (int i = 0; i < split.length; i++) {
			String[] ss = split[i].split(":");
			m.put(ss[0], ss[1]);
		}
//		System.out.println(m.toString());
		return m;
	}

	public String addCentrifugalDetails(Map<String, Object> map) {
		/*我发送信息：
		1）0   //代表成功
		2）1   //代表离心机编号和操作状态码 不正确或为空
		3）2   //该离心机不在绑定状态，无法操作
		4）3   //该离心机未开始胶注（只能发启动状态）
		5）4   //该离心机胶注未结束不能进行开始操作
		6）5   //该离心机正在临时停止中不能进行停止操作
		7）6   //该离心机未临时停止不能进行临时启动
		8）7   //该离心机正在临时启动中不能在进行临时启动操作
		9）8   //该离心机正在临时停止中不能在进行临时停止操作
		 */		
		String message = null;
		// 离心机编号
		String ccode = null;
		// 操作状态 1启动 0结束 2临时启动 3临时停止
		String stare = null;
		//温度
		String cdremark4 = null;
		/** A面：胶注时间*//*
		String pouringTime = null;
		*//** A面：胶注温度*//*
		String pouringTemperature = null;
		*//** A面：拆卸时间*//*
		String apartTime = null;
		*//** A面：拆卸硬度*//*
		String apartHardness = null;
		*//** B面：胶注时间*//*
		String pouringTime2 = null;
		*//** B面：胶注温度*//*
		String pouringTemperature2 = null;
		*//** B面：拆卸时间*//*
		String apartTime2 = null;
		*//** B面：拆卸硬度*//*
		String apartHardness2 = null;*/
		for (Entry<String, Object> entry : map.entrySet()) { 
			if("ccode".equals(entry.getKey())){
				ccode = entry.getValue().toString();
			}
			if("stare".equals(entry.getKey())){
				stare = entry.getValue().toString();
			}
			if("cdremark4".equals(entry.getKey())){
				cdremark4 = entry.getValue().toString();
			}
			/*if("pouringTime".equals(entry.getKey())){
				pouringTime = entry.getValue().toString();
			}
			if("pouringTemperature".equals(entry.getKey())){
				pouringTemperature = entry.getValue().toString();
			}
			if("apartTime".equals(entry.getKey())){
				apartTime = entry.getValue().toString();
			}
			if("apartHardness".equals(entry.getKey())){
				apartHardness = entry.getValue().toString();
			}
			if("pouringTime2".equals(entry.getKey())){
				pouringTime2 = entry.getValue().toString();
			}
			if("pouringTemperature2".equals(entry.getKey())){
				pouringTemperature2 = entry.getValue().toString();
			}
			if("apartTime2".equals(entry.getKey())){
				apartTime2 = entry.getValue().toString();
			}
			if("apartHardness2".equals(entry.getKey())){
				apartHardness2 = entry.getValue().toString();
			}*/
		}
		
		if(null != ccode &&  null != stare){
			SimpleDateFormat sDateFormat = new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss");
			String date = sDateFormat.format(new Date());

			// 根据离心机编号查询当前离心机
			CentrifugalExample example = new CentrifugalExample();
			Criteria createCriteria = example.createCriteria();
			// 离心机编号
			createCriteria.andCcodeEqualTo(ccode);
			createCriteria.andCremarkIsNull();
			// 是否报废 1是 0否
			createCriteria.andCremark1EqualTo("0");
			List<Centrifugal> centrifugals = centrifugalServise
					.selectByExample(example);

			// 根据离心机编号查询当前离心机胶注详情

			// 该离心机编号是离心机
			if (centrifugals.size() > 0) {
				// 离心机绑定id
				Long cid = null;
				// 离心机绑定id2
				Long cid2 = null;
				cid = centrifugals.get(0).getCid();
				
				//膜管1
				WorkCentrifugalDetails centrifugalDetails = new WorkCentrifugalDetails();
				centrifugalDetails.setCid(String.valueOf(cid));
				List<WorkCentrifugalDetails> list = workCentrifugalDetailsService
						.queryAllByMution(centrifugalDetails);
				
				//膜管2
				WorkCentrifugalDetails centrifugalDetails2 = new WorkCentrifugalDetails();
				List<WorkCentrifugalDetails> list2 = new ArrayList<>();
				
				if (centrifugals.size() >= 2) {
					cid2 = centrifugals.get(1).getCid();
					centrifugalDetails2.setCid(String.valueOf(cid2));
					list2 = workCentrifugalDetailsService
							.queryAllByMution(centrifugalDetails2);
				}
				// 找到最后一次胶注
				if (list.size() > 0) {
					// 未结束
					if ("".equals(list.get(list.size() - 1).getCdremark1())
							|| list.get(list.size() - 1).getCdremark1() == null) {
						centrifugalDetails = list.get(list.size() - 1);
						// N遍胶
						if ("1".equals(stare)) {
							message = "4";
							// 结束
						} else if ("0".equals(stare)) {
							String cdremark2 = centrifugalDetails.getCdremark2();
							// 未临时停止
							if ("".equals(cdremark2) || null == cdremark2) {
								// 开始时间
								String cdremark = centrifugalDetails.getCdremark();
								// 计算开始时间到此刻的时间差
								String timeDifference = getTimeDifference(date,
										cdremark);
								// 保存胶注时间
								centrifugalDetails.setCdremark3(timeDifference);
								// 结束时间
								centrifugalDetails.setCdremark1(date);
								workCentrifugalDetailsService
										.update(centrifugalDetails);
								if (cid2 != null) {
									centrifugalDetails2 = list2.get(list2.size() - 1);
									// 保存胶注时间
									centrifugalDetails2.setCdremark3(timeDifference);
									// 结束时间
									centrifugalDetails2.setCdremark1(date);
									workCentrifugalDetailsService
											.update(centrifugalDetails2);
								}
								
								//修改离心机状态
								deviceUpdateStare(ccode, centrifugalDetails.getCdtype(), 3,stare,date);
								message = "0";
							//临时停止中
							} else if ("-1".equals(cdremark2)) {
								message = "5";
							//临时开始时间
							}else{
								// 计算临时开始时间到此刻的时间差
								String timeDifference = getTimeDifference(date,
										cdremark2);
								//胶注时间 = 胶注时间+时间差
								timeDifference = addTime(timeDifference, centrifugalDetails.getCdremark3());
								// 保存胶注时间
								centrifugalDetails.setCdremark3(timeDifference);
								// 结束时间
								centrifugalDetails.setCdremark1(date);
								workCentrifugalDetailsService
										.update(centrifugalDetails);
								if (cid2 != null) {
									
									centrifugalDetails2 = list2.get(list2.size() - 1);
									// 保存胶注时间
									centrifugalDetails2.setCdremark3(timeDifference);
									// 结束时间
									centrifugalDetails2.setCdremark1(date);
									workCentrifugalDetailsService
											.update(centrifugalDetails2);
								}
								//修改离心机状态
								deviceUpdateStare(ccode, centrifugalDetails.getCdtype(), 3,stare,date);
								message = "0";
							}
						//临时启动
						} else if ("2".equals(stare)) {
							String cdremark2 = centrifugalDetails.getCdremark2();
							// 未临时停止
							if ("".equals(cdremark2) || null == cdremark2) {
								message = "6";
							//临时停止中
							} else if ("-1".equals(cdremark2)) {
								// 临时开始时间
								centrifugalDetails.setCdremark2(date);
								workCentrifugalDetailsService
										.update(centrifugalDetails);
								if (cid2 != null) {
									centrifugalDetails2 = list2.get(list2.size() - 1);
									// 临时开始时间
									centrifugalDetails2.setCdremark2(date);
									workCentrifugalDetailsService
											.update(centrifugalDetails2);
								}
								message = "0";
							//临时开始时间
							}else{
								message = "7";
							}
						//临时停止
						} else if ("3".equals(stare)) {
							String cdremark2 = centrifugalDetails.getCdremark2();
							// 未临时停止
							if ("".equals(cdremark2) || null == cdremark2) {
								// 开始时间
								String cdremark = centrifugalDetails.getCdremark();
								// 计算开始时间到此刻的时间差
								String timeDifference = getTimeDifference(date,
										cdremark);
								// 保存胶注时间
								centrifugalDetails.setCdremark3(timeDifference);
								// 临时开始时间  = -1 停止中
								centrifugalDetails.setCdremark2("-1");
								workCentrifugalDetailsService
										.update(centrifugalDetails);
								if (cid2 != null) {
									centrifugalDetails2 = list2.get(list2.size() - 1);
									// 保存胶注时间
									centrifugalDetails2.setCdremark3(timeDifference);
									// 临时开始时间  = -1 停止中
									centrifugalDetails2.setCdremark2("-1");
									workCentrifugalDetailsService
											.update(centrifugalDetails2);
								}
								message = "0";
							//临时停止中
							} else if ("-1".equals(cdremark2)) {
								message = "8";
							//临时开始时间
							}else{
								// 计算临时开始时间到此刻的时间差
								String timeDifference = getTimeDifference(date,
										cdremark2);
								//胶注时间 = 胶注时间+时间差
								timeDifference = addTime(timeDifference, centrifugalDetails.getCdremark3());
								// 保存胶注时间
								centrifugalDetails.setCdremark3(timeDifference);
								// 临时开始时间  = -1 停止中
								centrifugalDetails.setCdremark2("-1");
								workCentrifugalDetailsService
										.update(centrifugalDetails);
								if (cid2 != null) {
									centrifugalDetails2 = list2.get(list2.size() - 1);
									// 保存胶注时间
									centrifugalDetails2.setCdremark3(timeDifference);
									// 临时开始时间  = -1 停止中
									centrifugalDetails2.setCdremark2("-1");
									workCentrifugalDetailsService
											.update(centrifugalDetails2);
								}
								message = "0";
							}
						}else{
							message = "1";
						}
					// 结束   
					} else {
						String cdtype = list.get(list.size() - 1).getCdtype();
						//不够三次胶注
						if(Integer.parseInt(cdtype) <= 3){
							int parseInt = Integer.parseInt(cdtype) + 1;
							// N+1遍胶
							if ("1".equals(stare)) {
								
								/*centrifugalDetails.setPouringTime(pouringTime);
								centrifugalDetails.setPouringTemperature(pouringTemperature);
								centrifugalDetails.setApartTime(apartTime);;
								centrifugalDetails.setApartHardness(apartHardness);
								centrifugalDetails.setPouringTime2(pouringTime2);
								centrifugalDetails.setPouringTemperature2(pouringTemperature2);
								centrifugalDetails.setApartTime2(apartTime2);;
								centrifugalDetails.setApartHardness2(apartHardness2);*/
								centrifugalDetails.setCdremark4(cdremark4);
								
								
								centrifugalDetails.setCdtype(String.valueOf(parseInt));
								centrifugalDetails.setCdremark(date);
								centrifugalDetails.setCdremark3("0");
								workCentrifugalDetailsService
										.insert(centrifugalDetails);
								if (cid2 != null) {
									centrifugalDetails.setCid(String.valueOf(cid2));
									workCentrifugalDetailsService
											.insert(centrifugalDetails);
								}
						        //修改离心机状态
								deviceUpdateStare(ccode, centrifugalDetails.getCdtype(), 3,stare,date);
								message = "0";
							} else {
								message = "3";
							}
						//够三次胶注
						} else {
							message = "2";
						}
					}
					// 一遍胶
				} else {
					if ("1".equals(stare)) {
						
						/*centrifugalDetails.setPouringTime(pouringTime);
						centrifugalDetails.setPouringTemperature(pouringTemperature);
						centrifugalDetails.setApartTime(apartTime);;
						centrifugalDetails.setApartHardness(apartHardness);
						centrifugalDetails.setPouringTime2(pouringTime2);
						centrifugalDetails.setPouringTemperature2(pouringTemperature2);
						centrifugalDetails.setApartTime2(apartTime2);;
						centrifugalDetails.setApartHardness2(apartHardness2);*/
						centrifugalDetails.setCdremark4(cdremark4);
						
						centrifugalDetails.setCdtype("1");
						centrifugalDetails.setCdremark(date);
						centrifugalDetails.setCdremark3("0");
						workCentrifugalDetailsService.insert(centrifugalDetails);
						if (cid2 != null) {
							centrifugalDetails.setCid(String.valueOf(cid2));
							workCentrifugalDetailsService
									.insert(centrifugalDetails);
						}
						
						//修改离心机状态
						deviceUpdateStare(ccode, centrifugalDetails.getCdtype(), 3,stare,date);
						
						message = "0";
					} else {
						message = "3";
					}
				}
			} else {
				message = "2";
			}
		}else{
			message = "1";
		}
		return message;
	}

	/***
	 * @comments 计算两个时间的时间差
	 * @param strTime1
	 * @param strTime2
	 */
	public static String getTimeDifference(String strTime1, String strTime2) {
		// 格式日期格式，在此我用的是"2018-01-24 19:49:50"这种格式
		// 可以更改为自己使用的格式，例如：yyyy/MM/dd HH:mm:ss 。。。
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			Date now = df.parse(strTime1);
			Date date = df.parse(strTime2);
			long l = now.getTime() - date.getTime(); // 获取时间差
			long minAll = ((l / (60 * 1000)));
			long day = l / (24 * 60 * 60 * 1000);
			long hour = (l / (60 * 60 * 1000) - day * 24);
			long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
//			System.out.println("时间差" + day + "天" + hour + "小时" + min + "分");
			return "" + minAll + "分";
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/***
	 * 时间差求和
	 * 
	 * @param time
	 *            ...分
	 */
	public static String timeDifference(String time) {
		// 格式日期格式，在此我用的是"2018-01-24 19:49:50"这种格式
		// 可以更改为自己使用的格式，例如：yyyy/MM/dd HH:mm:ss 。。。
		try {
			time = time.replace("分", "");
			long min = Long.valueOf(time);
			long day = min / (24 * 60);
			long hour = (min / (60) - day * 24);
			min = (min - day * 24 * 60 - hour * 60);
//			System.out.println("" + day + "天" + hour + "小时" + min + "分");
			return "" + day + "天" + hour + "小时" + min + "分";
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 
	 * @param time
	 * @param oldTime
	 * @return
	 */
	public String addTime(String time, String oldTime) {
		oldTime = oldTime.replace("分", "");
		time = time.replace("分", "");
		time = String.valueOf(Long.valueOf(oldTime) + Long.valueOf(time)) + "分";
		return time;
	}
	
	/**
	 * 修改离心机状态
	 * @param ccode 离心机编号
	 * @param cdtype 此次胶注
	 * @param lastCdtype 最后一次胶注
	 * @param stare 操作状态 1启动 0结束 2临时启动 3临时停止
	 */
	public void deviceUpdateStare(String ccode, String cdtype,int lastCdtype,String stare,String date) {
		//修改离心机状态
		DeviceModel deviceModel = new DeviceModel();
		deviceModel.setDeviceNo(ccode);
		List<DeviceModel> devices = othersService.deviceByMution(deviceModel );
        if(devices.size() == 1){
        	//启动
        	if("1".equals(stare)){
        		deviceModel.setId(devices.get(0).getId());
        		if(Integer.parseInt(cdtype) > lastCdtype){
        			deviceModel.setRemark05("空闲");
        		}else{
        			deviceModel.setRemark05(cdtype+"遍胶");
        		}
        		//修改
        		othersService.deviceUpdate(deviceModel);
        	}else if("0".equals(stare)){
        		if(Integer.parseInt(cdtype) >= lastCdtype){
        			deviceModel.setId(devices.get(0).getId());
        			deviceModel.setRemark05("空闲");
        			//修改
        			othersService.deviceUpdate(deviceModel);
        			
        			// 根据离心机编号查询当前离心机
        			CentrifugalExample example = new CentrifugalExample();
        			Criteria createCriteria = example.createCriteria();
        			// 离心机编号
        			createCriteria.andCcodeEqualTo(ccode);
        			createCriteria.andCremarkIsNull();
        			// 是否报废 1是 0否
        			createCriteria.andCremark1EqualTo("0");
        			List<Centrifugal> centrifugals = centrifugalServise
        					.selectByExample(example);
        			for (int i = 0; i < centrifugals.size(); i++) {
        				Centrifugal centrifugal = centrifugals.get(i);
        				centrifugal.setCremark(date);
        				centrifugalServise.updateByPrimaryKeySelective(centrifugal);
					}
        		}
        	}
        }
	}
}
